package com.yunji.system.filter;

import com.yunji.common.cache.RedisCache;
import com.yunji.common.model.dto.LoginInfo;
import com.yunji.common.utils.StringUtils;
import com.yunji.common.utils.bean.BeanUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Collection;

import static com.yunji.common.constant.Constants.LOGIN_USER_KEY;
import static com.yunji.common.constant.Constants.STR_NULL;
import static com.yunji.common.constant.General.TOKEN_PREFIX;

/**
 * @Project: yunji-coffee
 * @Package: com.yunji.framework.security.filter
 * @Title: WechatFilter
 * @Description: 微信用户过滤器
 * History:
 * Date						Version			Author			Summary
 * ========================================================================
 * 2024-04-26 11:53:54		V1.0			HuaAo		新建类
 */
@Component
public class WechatFilter implements Filter {
    private static final Logger logs = LoggerFactory.getLogger(WechatFilter.class);

    private static final String GATEWAY_PREFIX = "/gateway";

    @Lazy
    @Resource
    private RedisCache redis;

    @Value("${token.secret}")
    private String secret;

    // 令牌自定义标识l
    @Value("${token.header}")
    private String header;

    private final String ignore = "/gateway/home/loginByStaff," +
            "/gateway/home/loginByWeixin," +
            "/gateway/home/loginStaffByWeixin," +
            "/gateway/audit/operate," +
            "/gateway/upload," +
            "/gateway/listener," +
            "/gateway/chip/upgrade," +
            "/gateway/wechat/trade/callback," +
            "/gateway/wechat/refund/callback," +
            "/gateway/wechat/recharge/callback," +
            "/gateway/wechat/payout/callback," +
            "/gateway/alipay/payout/callback," +
            "/gateway/product/productList," +
            "/gateway/product/productTypeList," +
            "/gateway/container/createScanMsg," +
            "/gateway/container/getContainerType," +
            "/gateway/text/privacyText," +
            "/gateway/order/syncHistoryOrder";

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        if (RequestMethod.OPTIONS.name().equalsIgnoreCase(httpRequest.getMethod())) {
            // 预检处理
            chain.doFilter(request, response);
            return;
        }
        String uri = httpRequest.getServletPath();
        if (uri.indexOf(GATEWAY_PREFIX) != 0) {
            chain.doFilter(request, response);
            return;
        }
        logs.info("【微信小程序请求】请求路径:{}", uri);
        if (ignore.contains(uri)) {
            chain.doFilter(request, response);
            return;
        }
        String token = getToken(httpRequest);
        Assert.isTrue(BeanUtils.isNotNull(token), StringUtils.format("非法请求{}", uri));
        Claims claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
        String uuid = (String) claims.get(LOGIN_USER_KEY);
        Collection<String> keys = redis.keys("sys_*");
        //System.out.println("--------------------" + keys);
        logs.trace("【微信小程序请求】UUID:{}", uuid);
        Assert.isTrue(redis.hasKey(uuid), "token失效");
        LoginInfo info = redis.get(uuid);
        String userType = info.getUserType();
        logs.trace("【微信小程序请求】用户类型{}", userType);
        //Assert.isTrue(SystemContext.isApp(), StringUtils.format("非法请求{}", uri));
        chain.doFilter(request, response);
    }

    private String getToken(HttpServletRequest request) {
        String token = request.getHeader(header);
        if (BeanUtils.isNotNull(token) && token.startsWith(TOKEN_PREFIX)) {
            token = token.replace(TOKEN_PREFIX, STR_NULL);
        }
        logs.trace("【微信小程序请求】处理收Token信息:{}", token);
        return token;
    }
}